/* eslint-disable no-unused-expressions */
import React, { Component } from 'react';
import { Bind } from 'lodash-decorators';
import { isNil, isPlainObject, isFunction } from 'lodash';
import { computed } from 'mobx';
import { observer } from 'mobx-react';
import { Tooltip, Spin } from 'hzero-ui';
import { Icon } from 'choerodon-ui';
import { DataSet, Table, DatePicker } from 'choerodon-ui/pro';
import { DataSetStatus } from 'choerodon-ui/pro/lib/data-set/enum';
import moment from 'moment';

import { Button as ButtonPermission } from 'components/Permission';
import { Header, Content } from 'components/Page';
import formatterCollections from 'utils/intl/formatterCollections';
import intl from 'utils/intl';

import { MacroCode } from 'tmsCommon/htms/code/macroCode';
import multilingualCode from 'tmsCommon/MultilingualCode';

import { listDS } from './store/indexDS';
import { queryGanttData } from './api';
import { handleMacro, handleResponse, isDate } from './utils/utils';
import { handleGanttDataReceive, findX } from './utils/gantt';
import RailwayGantt from './RailwayGantt';

const { HTMS_MUTIL_COMMON, HTMS_MUTIL_SHIPMENT_STOP } = multilingualCode;

@formatterCollections({ code: [HTMS_MUTIL_COMMON, HTMS_MUTIL_SHIPMENT_STOP] })
@observer
class List extends Component {
  constructor(props) {
    super(props);

    this.state = {
      submitLoading: false,
      cancelLoading: false,
      // 甘特图被选中的任务
      selectedTask: null,
      // 甘特图数据
      ganttData: [],
      spinning: false,
      // 被选中的行id
      selectedRowId: null,
      // 分钟步长
      minuteStep: 20,
    };

    this.tableDS = new DataSet(listDS(this));
    this.gantt = null;
  }

  componentDidMount() {
    this.queryData();
  }

  setMinuteStep = (step, cb) => {
    this.setState(
      {
        minuteStep: step,
      },
      () => {
        if (isFunction(cb)) {
          cb();
        }
      }
    );
  };

  @Bind
  setSelectedRowId(id) {
    this.setState({
      selectedRowId: id,
    });
  }

  @Bind
  getSelectedRecord() {
    const { selectedRowId } = this.state;
    const selectedRecord = this.tableDS.find((record) => {
      return !isNil(selectedRowId) && record.get('id') === selectedRowId;
    });
    return selectedRecord;
  }

  @Bind
  selectedRecord() {
    const record = this.getSelectedRecord();
    if (record) {
      this.tableDS.select(record);
    }
  }

  @Bind
  setSelectedTask(task) {
    this.setState({
      selectedTask: task,
    });
  }

  @Bind
  async queryData() {
    return this.tableDS.query(this.tableDS.currentPage);
  }

  @Bind
  queryGanttData() {
    const { minuteStep } = this.state;
    const { selected } = this.tableDS;
    if (selected && selected.length) {
      const record = selected[0];
      this.setState({ spinning: true });
      const param = {
        locationGid: record.get('locationGid'),
        ganttDate: `${this.gantt?.getGanttDate()} 00:00:00`,
        id: record.get('id'),
      };
      queryGanttData(param)
        .then((response) => {
          handleResponse(
            response,
            (data) => {
              const ganttData = handleGanttDataReceive(data, this.gantt?.getGanttDate(), {
                stopType: record.get('stopType'),
              });
              const x = findX(data, minuteStep);
              this.setState(
                {
                  ganttData,
                },
                () => {
                  this.gantt?.updateGantt(x);
                }
              );
            },
            () => {
              this.setState(
                {
                  ganttData: [],
                },
                () => {
                  this.gantt?.updateGantt(0);
                }
              );
            }
          );
        })
        .finally(() => {
          this.setState({ spinning: false });
        });
    } else {
      this.gantt?.clearAll();
    }
  }

  @Bind
  handleSubmit() {
    const { selected } = this.tableDS;
    const { selectedTask } = this.state;
    if (selected && selected.length && isPlainObject(selectedTask)) {
      const data = {
        dockGid: selectedTask.dockGid,
        dockResourceLineGid: selectedTask.dockResourceLineGid,
        appointmentDate: selectedTask.appointmentDate,
      };
      const record = selected[0];
      const list = [
        {
          id: record.get('id'),
        },
      ];
      const config = {
        data,
        list,
        macroCode: MacroCode.TMS_SS_SUBMIT_APPOINTMENT,
        onBefore: () => {
          this.setState({ submitLoading: true });
          this.setSelectedRowId(record.get('id'));
        },
        onFinish: () => {
          this.setState({ submitLoading: false });
          this.queryData().then(() => {
            this.selectedRecord();
          });
        },
      };
      handleMacro(config);
    }
  }

  @Bind
  handleCancel() {
    const { selected } = this.tableDS;
    if (selected && selected.length) {
      const record = selected[0];
      const list = [
        {
          id: record.get('id'),
        },
      ];
      const config = {
        list,
        macroCode: MacroCode.TMS_SS_CANCEL_APPOINTMENT,
        onBefore: () => {
          this.setState({ cancelLoading: true });
          this.setSelectedRowId(record.get('id'));
        },
        onFinish: () => {
          this.setState({ cancelLoading: false });
          this.queryData().then(() => {
            this.selectedRecord();
          });
        },
      };
      handleMacro(config);
    }
  }

  @computed
  get isActive() {
    return (
      this.tableDS && this.tableDS.status === DataSetStatus.ready && this.tableDS.selected.length
    );
  }

  get btns() {
    const {
      match: { path },
    } = this.props;
    const { submitLoading, cancelLoading, selectedTask } = this.state;
    return [
      <ButtonPermission
        type="c7n-pro"
        permissionList={[
          {
            code: `${path}.button.submit_appointment`,
            type: 'button',
            meaning: '预约平台-提交预约',
          },
        ]}
        funcType="flat"
        color="primary"
        icon="check"
        loading={submitLoading}
        disabled={!(this.isActive && selectedTask)}
        onClick={this.handleSubmit}
      >
        {intl.get(`${HTMS_MUTIL_SHIPMENT_STOP}.title.submit`).d('提交预约')}
      </ButtonPermission>,
      <ButtonPermission
        type="c7n-pro"
        permissionList={[
          {
            code: `${path}.button.cancel_appointment`,
            type: 'button',
            meaning: '预约平台-取消预约',
          },
        ]}
        funcType="flat"
        color="red"
        icon="close"
        loading={cancelLoading}
        disabled={!this.isActive}
        onClick={this.handleCancel}
      >
        {intl.get(`${HTMS_MUTIL_SHIPMENT_STOP}.title.cancel`).d('取消预约')}
      </ButtonPermission>,
    ];
  }

  @Bind
  renderAppointmentDate({ value }) {
    let appointmentDate = value;
    if (isDate(value)) {
      appointmentDate = moment(value).format('YYYY-MM-DD');
    }
    return appointmentDate;
  }

  @Bind
  renderDriverName({ value, record }) {
    const driverNumber = record.get('driverPhone');
    const idNumber = record.get('driverIdNumber');
    const tag = (
      <>
        <div
          style={{
            display: 'flex',
            justifyContent: 'space-between',
            alignItems: 'center',
          }}
        >
          <span>{isNil(value) ? '-' : value}</span>
          <Tooltip
            title={
              <>
                <div>
                  {intl.get(`${HTMS_MUTIL_SHIPMENT_STOP}.object.driverName`).d('司机名称')}：
                  {isNil(value) ? '-' : value}
                </div>
                <div>
                  {intl.get(`${HTMS_MUTIL_SHIPMENT_STOP}.object.driverNumber`).d('司机联系电话')}：
                  {isNil(driverNumber) ? '-' : driverNumber}
                </div>
                <div>
                  {intl.get(`${HTMS_MUTIL_SHIPMENT_STOP}.object.idNumber`).d('司机身份证号')}：
                  {isNil(idNumber) ? '-' : idNumber}
                </div>
              </>
            }
          >
            <Icon
              type="info_outline"
              style={{
                color: '#6785E7',
              }}
            />
          </Tooltip>
        </div>
      </>
    );
    return tag;
  }

  get columns() {
    return [
      { name: 'shipmentXid', lock: 'left', width: 150 },
      { name: 'totalItemCount', width: 80, align: 'right' },
      { name: 'totalWeight', width: 80, align: 'right' },
      { name: 'totalVolume', width: 80, align: 'right' },
      { name: 'locationName', width: 150 },
      { name: 'stopType', width: 120, align: 'center' },
      { name: 'plannedArrival', width: 160, align: 'center' },
      { name: 'servprovName', width: 150 },
      {
        name: 'driverName',
        width: 120,
        renderer: this.renderDriverName,
      },
      { name: 'equipmentNumber', width: 150 },
      { name: 'dockName', width: 150 },
      {
        name: 'appointmentDate',
        width: 160,
        align: 'center',
        renderer: this.renderAppointmentDate,
      },
      { name: 'appointmentSlot', width: 160, align: 'center' },
      { name: 'appointmentRejectReason', lock: 'right', width: 150, align: 'center' },
      {
        name: 'appointmentStatus',
        lock: 'right',
        width: 120,
        align: 'center',
      },
    ];
  }

  render() {
    const { spinning, ganttData, minuteStep } = this.state;
    return (
      <>
        <Header
          title={intl.get(`${HTMS_MUTIL_SHIPMENT_STOP}.title.appointmentPlatform`).d('预约平台')}
        />
        <Content>
          <Spin spinning={spinning} tip="Loading...">
            <Table
              dataSet={this.tableDS}
              columns={this.columns}
              buttons={this.btns}
              queryFields={{
                plannedArrival: <DatePicker colSpan={2} />,
              }}
              pagination={{
                pageSizeOptions: ['5', '10', '20', '50', '100'],
              }}
            />
          </Spin>
          <Spin spinning={spinning} tip="Loading...">
            <RailwayGantt
              data={ganttData}
              setSelectedTask={this.setSelectedTask}
              ref={(gantt) => {
                this.gantt = gantt;
              }}
              queryGanttData={this.queryGanttData}
              tableDS={this.tableDS}
              minuteStep={minuteStep}
              setMinuteStep={this.setMinuteStep}
            />
          </Spin>
        </Content>
      </>
    );
  }
}

export default List;
